#!/bin/bash
# FIXME:$Id:$
# Bash Unit library and program.
# Copyright (c) 2010 by Radek Hnilica
# This program can be distributed inder termss of GPL version 3 or higher.

### Program constants
declare -r BASHUNIT_PROGRAM_NAME=bashunit
declare -r BASHUNIT_PROGRAM_VERSION="0.0.0"
declare -r BASHUNIT_COPYRIGHT="2010 by Radek Hnilica"

# PROGRAM_....

declare -ir BASHUNIT_TRUE=1 BASHUNIT_FALSE=0
declare -ir BASHUNIT_OK=0 BASHUNIT_FAIL=1

# Assert functions
# All assert functions begins with prefix 'assert_'

function assert_equal() {
    local -r expected=$1 actual=$2
    local message="$3"

    if [[ "$expected" == "$actual" ]]; then
	bashunit_test_reporter $BASHUNIT_TRUE
    else
	bashunit_test_reporter $BASHUNIT_FALSE "${BASH_SOURCE[1]}:${BASH_LINENO[0]}:${FUNCNAME[1]} expected: $expected, got: $actual"
    fi
}

function assert_not_equal() {
    local -r expected=$1 actual=$2
    local message="$3"

    if [[ "$expected" != "$actual" ]]; then
	bashunit_test_reporter $BASHUNIT_TRUE
    else
	bashunit_test_reporter $BASHUNIT_FALSE "${BASH_SOURCE[1]}:${BASH_LINENO[1]}:${FUNCNAME[1]}"
    fi
}

function assert_not_null() {
    local -r value=$1
    local message="$2"

    if [[ -n "$value" ]]; then
	bashunit_test_reporter $BASHUNIT_TRUE
    else
	bashunit_test_reporter $BASHUNIT_FALSE "${BASH_SOURCE[1]}:${BASH_LINENO[0]}:${FUNCNAME[1]}"
    fi
}

function assert_null() {
    local -r value=$1
    local message="$2"

    if [[ -z "$value" ]]; then
	bashunit_test_reporter $BASHUNIT_TRUE
    else
	bashunit_test_reporter $BASHUNIT_FALSE "${BASH_SOURCE[1]}:${BASH_LINENO[0]}:${FUNCNAME[1]}"
    fi
}


# Usage: assert_true $value
function assert_true() { echo "$FUNCNAME not yet implemented."; exit 1; }
function assert_false() { echo "$FUNCNAME not yet implemented."; exit 1; }


# This function is responsible for reporting result of one test.
function bashunit_test_reporter() {
    $bashunit_test_reporter "$@"
}

function bashunit_dot_reporter() {
    local -ir success="$1"
    shift
    local -r rest="$*"

    if ((success)); then
	echo -n .
    else
	echo  F
	echo "$rest"
    fi
}


function bashunit_runSuite() {
    local -r suiteFile=$1
    local test_case tests

    source $suiteFile
    local -r tests=$(declare -F|awk '{print $(NF)}'|grep ^test)

    if declare -F|grep "setUp$"; then
	eval setUp
    fi
    for test_case in $tests; do
	eval $test_case
	: ? report
	unset -f $test_case
    done
    if declare -F|grep "tearDown$"; then
	eval tearDown
    fi
    unset -f setUp tearDown
}



# Display the program usage.
bashunit_echo_usage() {
    bashunit_echo_version
    echo "usage: $BASHUNIT_PROGRAM_NAME [-dvhDV]"
    cat <<EOF
 -d,--debug     display debug messages, increase debug level
 -v,--verbose   be more verbose, increase verbosity level
 -h,--help      display this little help
 -D,--description  display program description
 -V,--version   display program version
EOF
}

# Print the program version.
bashunit_echo_version() {
    echo "$BASHUNIT_PROGRAM_NAME $BASHUNIT_PROGRAM_VERSION rev $BASHUNIT_PROGRAM_REVISION  $BASHUNIT_COPYRIGHT"
}

# Display program description.
bashunit_echo_description() {
    echo "$DESCRIPTION"|grep -v "^ *$"
}

### Command Line Arggument Parser.
# Declaring variables and theirs initial values.
declare bashunit_rest_args=
declare -i bashunit_option_verbose=$BASHUNIT_FALSE bashunit_verbosity_level=0
declare -i bashunit_option_debug=$BASHUNIT_FALSE bashunit_debug_level=0
declare -i bashunit_option_quiet=$BASHUNIT_FALSE
declare -i bashunit_option_silent=$BASHUNIT_FALSE

bashunit_parse_arguments() {
    local option
    local -i fatal=$FALSE
    eval set -- "${bashunit_arguments}"
    while true; do
	option=$1; shift
	case "$option" in
	    -d|--debug)         bashunit_option_debug=$BASHUNIT_TRUE
		                ((bashunit_debug_level++));;
	    -v|--verbose)       bashunit_option_verbose=$BASHUNIT_TRUE
		                ((bashunit_verbosity_level++));;
	    -h|--help)          bashunit_echo_usage; exit 0;;
	    -D|--description)   bashunit_echo_description; exit 0;;
	    -V|--version)       bashunit_echo_version; exit 0;;
	    --) bashunit_rest_args="$@"; break;; # Stop parsing arguments on --
	    *)	echo "$BASHUNIT_PROGRAM_NAME: Argument parsing error: ($option): $*"
		exit 1
		;;
	esac
    done

    # Do some checking of mandatory arguments.  Display error if
    # missing and set fatal=$TRUE.

    #if ! ((option_a)); then
    #	echo "Mandatory option -a missing"
    #	fatal=$BASHUNIT_TRUE
    #fi

    if ((fatal)); then
	echo "There was an fatal error.  Exitting!"
	exit 1
    fi
} # bashunit_parse_arguments()

#######   Startup code.   ##############################################

# Parse command line options
bashunit_arguments=$(getopt -u -n $BASHUNIT_PROGRAM_NAME \
    -o "dhvDV" \
    -l "debug description help verbose version" \
    -- "$@")
bashunit_parse_arguments

if ((bashunit_option_debug)); then
    bashunit_echo_version
    set -x
fi

#####   M A I N   ######################################################

bashunit_test_reporter=bashunit_dot_reporter

for bashunit_suite in $bashunit_rest_args; do
    bashunit_runSuite $bashunit_suite
done


#Emacs local configuration part.  Keep this at the end of the file.
#Local variables:
#coding: utf-8
#mode: shell-script
#End:

# Vim local configuration part.  Keep this ath the end of the file.
# vim:et:ft=sh:sts=2:sw=2
# vim:foldmethod=marker:foldmarker=#+,-#
